﻿using RotovapPlatform.Domain.Equipment.Device.TemperatureCollector.Dto;
using RotovapPlatform.Domain.Equipment.Interfaces.Base;
using RotovapPlatform.Domain.Equipment.Interfaces.Communication;
using RotovapPlatform.Domain.Common.Exceptions;
using Microsoft.Extensions.Logging;

namespace RotovapPlatform.Infrastructure.Equipment.Devices.TemperatureCollector
{
	public class TemperatureCollectorDrive : ITemperatureCollectorBase
	{
		private readonly ISerialServerManager _serverManager;
		private readonly ILogger<TemperatureCollectorDrive> _logger;
		private readonly int _port;
		private readonly byte _slaveId;

		public TemperatureCollectorDrive(
			ISerialServerManager serverManager,
			int port,
			byte slaveId,
			string name,
			ILogger<TemperatureCollectorDrive> logger)
		{
			_serverManager = serverManager;
			_port = port;
			_slaveId = slaveId;
			_logger = logger;
			Name = name;
			EquipmentId = $"TempCollector_{port}_{slaveId}";
		}

		public string Name { get; }
		public string EquipmentId { get; }

		public async Task<TemperatureCollectorStatus> GetTemperatureCollectorStatusAsync()
		{
			try
			{
				// 根据协议，使用功能码03读取4个温度值
				var registers = await _serverManager.ReadHoldingRegistersAsync(
					_port,
					_slaveId,
					0x0000,  // 起始地址
					4        // 读取4个温度值
				);

				var status = new TemperatureCollectorStatus();

				// 解析温度值
				// 将每个寄存器值转换为温度：
				// 1. 转为2进制，最高位为0（正温度）
				// 2. 转为10进制后/10.0得到实际温度值
				for (int i = 0; i < 4; i++)
				{
					ushort rawValue = registers[i];
					// 确保最高位为0（正温度）
					rawValue &= 0x7FFF;  // 清除最高位
					double temperature = rawValue / 10.0;

					// 根据索引设置对应的温度值
					switch (i)
					{
						case 0:
							status.Temperature1 = temperature;
							break;
						case 1:
							status.Temperature2 = temperature;
							break;
						case 2:
							status.Temperature3 = temperature;
							break;
						case 3:
							status.Temperature4 = temperature;
							break;
					}
				}

				_logger.LogDebug("温度采集模块 {Name} 读取温度值: T1={T1:F1}℃, T2={T2:F1}℃, T3={T3:F1}℃, T4={T4:F1}℃",
					Name,
					status.Temperature1,
					status.Temperature2,
					status.Temperature3,
					status.Temperature4);

				return status;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "读取温度采集模块 {Name} 状态失败", Name);
				throw new CommunicationException($"读取温度采集模块状态失败: {ex.Message}", ex);
			}
		}
	}
}